package kpi.javatraining6.gnatiuk.tests;

import kpi.javatraining6.gnatiuk.src.teachingsystem.Difficulty;
import kpi.javatraining6.gnatiuk.src.tester.Questionnaire;
import kpi.javatraining6.gnatiuk.src.tester.question.MultipleAnswerQuestion;
import kpi.javatraining6.gnatiuk.src.tester.question.OwnAnswerQuestion;
import kpi.javatraining6.gnatiuk.src.tester.question.Question;
import kpi.javatraining6.gnatiuk.src.tester.question.SingleAnswerQuestion;
import kpi.javatraining6.gnatiuk.src.tester.user.User;
import kpi.javatraining6.gnatiuk.src.tester.user.UserProgress;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Arrays;


public class QuestionTest {

    String questionStr;
    ArrayList<String> answers;
    ArrayList<String> userAnswers;
    ArrayList<String> correctAnswers;
    Question question;
    ArrayList<Question> questions;
    Questionnaire questionnaire;
    User user;
    UserProgress userProgress;
    private static final String EASY = "EASY";
    private static final String NORMAL = "NORMAL";
    private static final String HARD = "HARD";

    @Before
    public void setUp() throws Exception {
        user = new User("jack", "jack");
        userProgress = user.getCurrentProgress("OOP");
        correctAnswers = new ArrayList<>();
        questionStr = "What is your favorite programming language?";
        answers = new ArrayList<>(Arrays.asList("Java", "C#", "Python"));
        userAnswers = new ArrayList<>();
        questions = new ArrayList<>();
        questionnaire=new Questionnaire(questions);
        question = new SingleAnswerQuestion(EASY, questionStr, answers, correctAnswers);
    }

    @Test
    public void testEqualsToNotQuestion() {
        assertFalse(question.equals(new Object()));
    }

    @Test
    public void testGetTopic() {
        Question someQuestion = new Question("EASY", "", answers, correctAnswers) {
            @Override
            protected String determineQuestionNote() {
                return "Coca-Cola";
            }
        };
        assertEquals("Тема не определена", someQuestion.getTopic());
    }

    @Test
    public void testOwnAnswerTheQuestion() throws Exception {
        correctAnswers.add("java");
        question = new OwnAnswerQuestion(EASY, questionStr, answers, correctAnswers);
        userAnswers.add("java");
        boolean rez = question.answerTheQuestion(userAnswers);
        assertTrue("must be true", rez );
    }

    @Test
    public void testOwnAnswerTheQuestionToFalse() throws Exception {
        correctAnswers.add("java");
        question = new OwnAnswerQuestion(EASY, questionStr, answers, correctAnswers);
        userAnswers.add("C#");
        boolean rez = question.answerTheQuestion(userAnswers);
        assertFalse("must be false", rez);
    }

    @Test
    public void testSingleAnswerTheQuestion() throws Exception {
        correctAnswers.add("2");
        question = new SingleAnswerQuestion(EASY, questionStr, answers, correctAnswers);
        userAnswers.add("2");
        boolean rez = question.answerTheQuestion(userAnswers);
        assertTrue("must be true", rez );
    }

    @Test
    public void testSingleAnswerTheQuestionToFalse() throws Exception {
        correctAnswers.add("2");
        question = new SingleAnswerQuestion(EASY, questionStr, answers, correctAnswers);
        userAnswers.add("1");
        boolean rez = question.answerTheQuestion(userAnswers);
        assertFalse("must be false", rez);
    }

    @Test
    public void testMultipleAnswerTheQuestion() throws Exception {
        correctAnswers.add("1");
        correctAnswers.add("2");
        question = new MultipleAnswerQuestion(EASY, questionStr, answers, correctAnswers);
        userAnswers.add("2");
        userAnswers.add("1");
        boolean rez = question.answerTheQuestion(userAnswers);
        assertTrue("must be true", rez );
    }

    @Test
     public void testMultipleAnswerTheQuestionToFalse() throws Exception {
        correctAnswers.add("1");
        correctAnswers.add("2");
        question = new MultipleAnswerQuestion(EASY, questionStr, answers, correctAnswers);
        userAnswers.add("2");
        userAnswers.add("3");
        boolean rez = question.answerTheQuestion(userAnswers);
        assertFalse("must be false", rez);
    }

    @Test
    public void testQuestionnaireGetNormalQuestion() throws Exception {
        question = new SingleAnswerQuestion(NORMAL, questionStr, answers, correctAnswers);
        questions.add(question);
        question = questionnaire.nextQuestion(Difficulty.NORMAL);
        assertEquals("must be equal", Difficulty.NORMAL, question.getDifficulty());
    }

    @Test
    public void testQuestionnaireGetHardQuestion() throws Exception {
        question = new SingleAnswerQuestion(HARD, questionStr, answers, correctAnswers);
        questions.add(question);
        correctAnswers.add("1");
        userAnswers.add("1");
        for (int i = 0; i < 3; i++) {
            userProgress.addToAnswered(question, userAnswers);
        }
        question = questionnaire.nextQuestion(userProgress.getCurrentDifficulty());
        assertEquals("must be equal", Difficulty.HARD, question.getDifficulty());
    }

    @Test
     public void testQuestionnaireGetEasyQuestion() throws Exception {
        questions.add(question);
        correctAnswers.add("1");
        userAnswers.add("2");
        for (int i = 0; i < 3; i++) {
            userProgress.addToAnswered(question, userAnswers);
        }
        questionnaire.hasMoreQuestions(userProgress.getCurrentDifficulty());
        question = questionnaire.nextQuestion(userProgress.getCurrentDifficulty());
        assertEquals("must be equal", Difficulty.EASY, question.getDifficulty());
    }

    @Test
    public void testToString() {
        assertEquals("must be same classes", String.class, question.toString().getClass());
    }
}
